<template>
  <textarea ref="codeEditor" placeholder="请输入..."></textarea>
</template>

<script>
import {
  defineComponent,
  onBeforeUnmount,
  onMounted,
  ref,
  toRefs,
  watch
} from 'vue';
// 引入全局实例

import _CodeMirror from 'codemirror/lib/codemirror';
// 核心样式
import 'codemirror/lib/codemirror.css';
import 'codemirror/addon/edit/matchbrackets';
import 'codemirror/addon/selection/active-line';
import 'codemirror/addon/hint/sql-hint';
import 'codemirror/addon/hint/show-hint';
import 'codemirror/addon/fold/foldgutter.css';
import 'codemirror/addon/display/fullscreen.css';
import 'codemirror/addon/dialog/dialog.css';
import 'codemirror/addon/search/matchesonscrollbar.css';
import 'codemirror/addon/scroll/simplescrollbars.css';
import 'codemirror/addon/scroll/simplescrollbars';
import 'codemirror/mode/sql/sql';

const CodeMirror = window.CodeMirror || _CodeMirror;

export default defineComponent({
  props: {
    modelValue: String,
    defaultValue: String,
    readOnly: {
      type: Boolean,
      default: false
    }
  },
  setup(props, context) {
    const { modelValue, defaultValue, readOnly } = toRefs(props);
    const codeEditor = ref();
    let editor;
    watch(modelValue, () => {
      if (
        editor != null &&
        modelValue.value &&
        modelValue.value !== editor.getValue()
      ) {
        // 触发v-model的双向绑定
        editor.setValue(modelValue.value);
      }
    });
    watch(readOnly, () => {
      if (editor != null) {
        editor.setOption('readOnly', readOnly.value);
      }
    });
    onMounted(() => {
      editor = CodeMirror.fromTextArea(codeEditor.value, {
        mode: 'sql', // 不设置的话，默认使用第一个引用
        tabSize: 2,
        value: modelValue.value,
        mime: 'text/javascript',
        indentWithTabs: false, // 在缩进时，是否需要把 n*tab宽度个空格替换成n个tab字符，默认为false
        smartIndent: true, // 自动缩进，设置是否根据上下文自动缩进（和上一行相同的缩进量）。默认为true
        lineNumbers: true, // 是否在编辑器左侧显示行号
        matchBrackets: true, // 括号匹配
        readOnly: readOnly.value,
        // 启用代码折叠相关功能:开始
        foldGutter: true,
        lineWrapping: true,
        gutters: [
          'CodeMirror-linenumbers',
          'CodeMirror-foldgutter',
          'CodeMirror-lint-markers',
          'breakpoints'
        ],
        // 启用代码折叠相关功能:结束
        styleActiveLine: true // 光标行高亮
      });
      // 监听编辑器的change事件
      editor.on('change', () => {
        // 触发v-model的双向绑定
        context.emit('update:modelValue', editor.getValue());
      });
      if (defaultValue.value) {
        editor.setValue(defaultValue.value);
      }
    });
    onBeforeUnmount(() => {
      if (editor !== null) {
        editor.toTextArea();
        editor = null;
      }
    });
    return { codeEditor };
  }
});
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less"></style>
